package com.hoyo.config;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.DispatcherType;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.annotation.Order;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.DelegatingFilterProxy;

import com.hoyo.domain.ModuleInfo;
import com.hoyo.service.ModuleService;
import com.hoyo.service.UserService;

@Configuration
public class ShiroConfig {
	
	@Resource
	private ModuleService moduleService;
	
	@Bean(name = "lifecycleBeanPostProcessor")
	public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
		return  new LifecycleBeanPostProcessor();
	}
	
	
	/**
	 * FilterRegistrationBean
	 * @return
	 */
	@Bean
	public FilterRegistrationBean filterRegistrationBean() {
		FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter")); 
        filterRegistration.setEnabled(true);
        filterRegistration.setOrder(2);
        filterRegistration.addUrlPatterns("/*");
        filterRegistration.setDispatcherTypes(DispatcherType.REQUEST);
        return filterRegistration;
	}
	
	@Bean
	public FilterRegistrationBean characterFilterRegistrationBean() {
		FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(characterEncodingFilter()); 
        filterRegistration.setEnabled(true);
        filterRegistration.setOrder(1);
        filterRegistration.addUrlPatterns("/*");
        filterRegistration.setDispatcherTypes(DispatcherType.REQUEST);
        return filterRegistration;
	}
	
	@Bean
	public CharacterEncodingFilter characterEncodingFilter(){
		return new CharacterEncodingFilter("UTF-8", true);
	}
	
	
	/**
	 * @see org.apache.shiro.spring.web.ShiroFilterFactoryBean
	 * @return
	 * @throws Exception 
	 */
	@Bean("shiroFilter")
	public ShiroFilterFactoryBean shiroFilter() throws Exception{
		ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
		bean.setSecurityManager(securityManager());
		bean.setLoginUrl("/login");
		bean.setUnauthorizedUrl("/unauthor");
		
		Map<String, String> filterChainDefinitionMap = new HashMap<>();
		/*
		 * 开放url配置
		 */
		filterChainDefinitionMap.put("/404", "anon");
		filterChainDefinitionMap.put("/500", "anon");
		filterChainDefinitionMap.put("/login", "anon");
		filterChainDefinitionMap.put("/register", "anon");
		filterChainDefinitionMap.put("/telephone/**", "anon");
		filterChainDefinitionMap.put("/unauthor", "anon");
		filterChainDefinitionMap.put("/index", "anon");
		filterChainDefinitionMap.put("/", "anon");
		filterChainDefinitionMap.put("/movie/**", "anon");
		
		/*try {
			List<ModuleInfo> modules = moduleService.findAllModules();
			System.out.println("setup permissions ...");
			
			 * 拼凑符合shiro框架定义的权限链
			 
		} catch (Exception e) {
			e.printStackTrace();
		}*/
		
		
		/*
		 * 用户url配置
		 */
////		弹幕
		filterChainDefinitionMap.put("/bullet/new", "user");
		filterChainDefinitionMap.put("/bullet/report", "user");
//		评论
		filterChainDefinitionMap.put("/comment/new", "user");
		filterChainDefinitionMap.put("/comment/report", "user");
		filterChainDefinitionMap.put("/comment/reply", "user");
//		视频
		filterChainDefinitionMap.put("/catalog/report", "user");
//		filterChainDefinitionMap.put("/movie/**", "user");
//		频道
//		filterChainDefinitionMap.put("/channel/channels", "user");
//		上下传
		filterChainDefinitionMap.put("/upload/**", "user");
//		个人信息
		filterChainDefinitionMap.put("/user/**", "user");
		
		/*
		 * 管理员配置url
		 */
		filterChainDefinitionMap.put("/admin/**", "authc,roles[admin]");
		
		bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		
		return bean;
	}
	
	/**
	 * @see org.apache.shiro.mgt.SecurityManager
	 * @return
	 */
	@Bean(name="securityManager")
	public DefaultWebSecurityManager securityManager() {
		DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
		manager.setRealm(userRealm());
		manager.setCacheManager(cacheManager());
		manager.setSessionManager(defaultWebSessionManager());
		return manager;
	}
	
	/**
	 * @see DefaultWebSessionManager
	 * @return
	 */
	@Bean(name="sessionManager")
	public DefaultWebSessionManager defaultWebSessionManager() {
		DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
		sessionManager.setCacheManager(cacheManager());
		sessionManager.setGlobalSessionTimeout(1800000);
		sessionManager.setDeleteInvalidSessions(true);
		sessionManager.setSessionValidationSchedulerEnabled(true);
		sessionManager.setDeleteInvalidSessions(true);
		sessionManager.setSessionIdCookie(simpleCookie());
		sessionManager.setSessionIdCookieEnabled(true);
		return sessionManager;
	}
	
	//AOP式方法级权限检查
	@Bean  
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {  
        DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();  
        daap.setProxyTargetClass(true);  
        return daap;  
    } 
	
	@Bean
    public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
        aasa.setSecurityManager(securityManager);
        return aasa;
    }
	
	/**
	 * @see UserRealm--->AuthorizingRealm
	 * @return
	 */
	@Bean
	@DependsOn(value="lifecycleBeanPostProcessor")
	public UserRealm userRealm() {
		UserRealm userRealm = new UserRealm();
		userRealm.setCacheManager(cacheManager());
		return userRealm;
	}
	
	@Bean
	public EhCacheManager cacheManager() {
		EhCacheManager cacheManager = new EhCacheManager();
		cacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
		return cacheManager;
	}
	
	/*
	 * 解决404页面返回要重新登录的问题
	 */
	@Bean
	public SimpleCookie simpleCookie(){
		return new SimpleCookie("HUYO_SESSION_ID");
	}
}









